﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using TlvLib.Packets;

namespace TlvLib.PacketParsers
{
    public class PacketParser : PacketParserBase, IPacketParser
    {
        public override bool CanParse(RawPacket packet)
        {
            return packet.MessageId == PacketType.LicensePlateInfo;
        }

        public override object Parse(RawPacket packet)
        {

            try
            {
                var stream = new MemoryStream(packet.Payload);
                var reader = new MiscUtil.IO.EndianBinaryReader(Config.EndianBitConverter, stream);

                var mb = reader.ReadBytes(32);
                var count = CountNonZero(mb);
                var m = AsciiEncoding.GetString(mb, 0, count);

                var db = reader.ReadBytes(8);
                count = CountNonZero(db);
                var dir = AsciiEncoding.GetString(db, 0, count);
                var c = reader.ReadInt32();
                var r = reader.ReadInt32();

                var buffer = reader.ReadBytes(16);
                count = CountNonZero(buffer);
                var plate = GbkEncoding.GetString(buffer, 0, count);
                var x = reader.ReadInt32();
                var y = reader.ReadInt32();
                var w = reader.ReadInt32();
                var h = reader.ReadInt32();

                var confidence = reader.ReadInt32();
                var pColor = reader.ReadInt16();
                var carType = reader.ReadInt16();
                var carColor = reader.ReadInt16();
                var wrongDir = reader.ReadByte();
                var detectMethod = reader.ReadByte();
                var speed = reader.ReadInt32();
                var speedLimit = reader.ReadInt32();
                var packIdBuffer = reader.ReadBytes(64);
                count = CountNonZero(packIdBuffer);
                var packId = AsciiEncoding.GetString(packIdBuffer, 0, count);

                var imgCount = reader.ReadInt16();

                if (imgCount <= 0)
                {
                    Log(string.Format("警告，车牌图片数目为 {0}", imgCount));
                }

                var imageDatas = new ImageData[imgCount];
                for (int i = 0; i < imgCount; i++)
                {
                    var year = reader.ReadInt16();
                    var month = reader.ReadInt16();
                    var d = reader.ReadInt16();
                    var hour = reader.ReadInt16();
                    var mm = reader.ReadInt16();
                    var s = reader.ReadInt16();
                    var ms = reader.ReadInt16();
                    var time = new DateTime(year, month, d, hour, mm, s, ms);

                    var imglen = reader.ReadInt32();

                    if (imglen <= 0 || imglen > Constants.MaxPacketSize)
                    {
                        Log("警告， 图片数据长度为 " + imglen);
                        throw new FormatException("数据包格式不正确，图片长度超长或者为负值");
                    }

                    var imgBuffer = reader.ReadBytes(imglen);

                    imageDatas[i] = new ImageData() { CaptureTime = time, ImageBuffer = imgBuffer };
                }

                var lpi = new LicensePlateInfo()
                              {
                                  CameraNo = c,
                                  Confidence = confidence,
                                  Images = imageDatas,
                                  MonitorId = m,
                                  CarType = carType,
                                  PlateNo = plate,
                                  PlateColor = pColor,
                                  PlatePosition = new Rectangle(x, y, w, h),
                                  RoadNo = r,
                                  PacketId = packId,
                                  Speed = speed,
                                  SpeedLimit = speedLimit,
                                  DetectMethod = detectMethod,
                                  Direction = dir,
                              };

                return lpi;
            }
            catch (Exception ex)
            {
                Log("解析车牌信息包出现错误：" + ex);
                throw;
            }
        }
    }
}
